import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Route, Router, CanActivateChild, CanLoad } from '@angular/router';
import { Observable, Observer } from 'rxjs/Rx';
import { AuthService } from "../auth.service";
import { ApplicationService } from "../application.service";
import { Title, Meta } from "@angular/platform-browser";

/**
 * 路由身份验证守卫
 * 
 * @export
 * @class AuthGuard
 * @implements {CanActivate}
 * @implements {CanActivateChild}
 * @implements {CanLoad}
 */
@Injectable()
export class AuthGuard implements CanActivate, CanActivateChild, CanLoad {

  /**
   * Creates an instance of AuthGuard.
   * @param {Title} htmlTitle 
   * @param {Meta} htmlMeta 
   * @param {ApplicationService} application 应用程序配置信息服务
   * @param {AuthService} authService 验证服务
   * @param {Router} router 路由
   * @memberof AuthGuard
   */
  constructor(
    private htmlTitle: Title,
    private htmlMeta: Meta,
    private application: ApplicationService,
    private authService: AuthService,
    private router: Router) {
  }
  /**
   * 允许异步加载
   * 
   * @param {Route} route 
   * @returns {(boolean | Observable<boolean> | Promise<boolean>)} 
   * @memberof AuthGuard
   */
  canLoad(route: Route): boolean | Observable<boolean> | Promise<boolean> {
    throw new Error("Method not implemented.");
  }
  /**
   * 允许激活子路由
   * 
   * @param {ActivatedRouteSnapshot} childRoute 
   * @param {RouterStateSnapshot} state 
   * @returns {(boolean | Observable<boolean> | Promise<boolean>)} 
   * @memberof AuthGuard
   */
  canActivateChild(childRoute: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {
    return this.canActivate(childRoute, state);
  }
  /**
   * 允许激活路由
   * 
   * @param {ActivatedRouteSnapshot} route 
   * @param {RouterStateSnapshot} state 
   * @returns {(boolean | Observable<boolean> | Promise<boolean>)} 
   * @memberof AuthGuard
   */
  canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<boolean> {    
    let url: string = state.url;
    this.authService.redirectUrl = url;
    return this.check(url);
  }

  private check(url: string): Observable<boolean> {
    return Observable.create(observer => { 
      //判断配置文件是否读取
      if (!this.application.appConfigData) {
        this.application.initAppConfigData().subscribe(
          next => {
            if (next.success) {
              //设置Html title
              this.htmlTitle.setTitle(this.application.appConfigData.appName);
              //设置Html description
              this.htmlMeta.addTag({ name: "description", content: this.application.appConfigData.appDescription });
              //检查逻辑
              this.checkLogic(observer, url);
            }
          },
          error => {
            observer.next(false);
            this.router.navigate(['/login']);
          }
        );
      }
      else {
        //检查逻辑
        this.checkLogic(observer, url);
      }
    });
  }

  /**
   * 
   * 
   * @private
   * @param {Observer<boolean>} observer 
   * @memberof AuthGuard
   */
  private checkLogic(observer: Observer<boolean>, url: string) {
    //添加下一行
    window.sessionStorage.setItem('callbackURL',window.location.href.split("callbackURL=")[1])

    if (!this.checkLogin()) {
      observer.next(false);
      this.authService.redirectUrl = url;      
      this.router.navigate(['/login']);
    }
    else if (!this.checkPermission()) {
      observer.next(false);
      this.authService.redirectUrl = url
      this.router.navigate(['/login']);
    }
    else if (!this.checkApplicationData()) {
      observer.next(false);
      this.authService.redirectUrl = url
      this.router.navigate(['/login']);    
    }
    else {
      observer.next(true);
    }
  }

  /**
   * 检查用户是否登录
   * 
   * @private
   * @returns {boolean} 
   * @memberof AuthGuard
   */
  private checkLogin(): boolean {
    if (this.application.loginData && this.application.loginData.loginState)
      return true;
    else
      return false;
  }

  /**
   * 检查系统参数是否存在
   * 
   * @private
   * @returns {boolean} 
   * @memberof AuthGuard
   */
  private checkApplicationData(): boolean {
    return this.application.initApplicationCompleted;
  }

  /**
   * 检查用户权限
   * 
   * @returns {boolean} 
   * 
   * @memberOf AuthGuard
   */
  private checkPermission(): boolean {
    return true;
  }
}



// WEBPACK FOOTER //
// ./src/app/service/guard/auth.guard.ts